Skip to content

[Storage] Create Session Support for GET Requests#47264

Merged
weirongw23-msft merged 31 commits into
Azure:storage/sessions-privatefrom
weirongw23-msft:weirongw23/sessions-private
Jun 5, 2026
Merged

[Storage] Create Session Support for GET Requests#47264
weirongw23-msft merged 31 commits into
Azure:storage/sessions-privatefrom
weirongw23-msft:weirongw23/sessions-private

Conversation

@weirongw23-msft
Copy link
Copy Markdown
Member

No description provided.

@weirongw23-msft weirongw23-msft marked this pull request as ready for review June 1, 2026 16:44
Copilot AI review requested due to automatic review settings June 1, 2026 16:44
@github-actions github-actions Bot added the Storage Storage Service (Queues, Blobs, Files) label Jun 1, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces opt-in “session-based” authentication for eligible GET blob requests (notably downloads) by adding a pipeline policy that can acquire/cache a short-lived session credential per container and use it to sign subsequent GET requests. It also adds the generated CreateSession REST operation/models and a new recorded test covering session behavior.

Changes:

  • Added StorageSessionPolicy + container-scoped session cache, and plumbed use_session=True into the sync pipeline creation path.
  • Added generated create_session operation + models/enums to support the service’s session creation API.
  • Added a recorded test and updated proxy sanitizers for session credentials.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
sdk/storage/azure-storage-blob/azure/storage/blob/_shared/policies.py Adds sync session auth policy + cache and request signing logic.
sdk/storage/azure-storage-blob/azure/storage/blob/_shared/base_client.py Adds use_session kwarg handling and wires StorageSessionPolicy into the sync pipeline.
sdk/storage/azure-storage-blob/azure/storage/blob/_shared/policies_async.py Introduces an async session policy stub (currently unimplemented).
sdk/storage/azure-storage-blob/azure/storage/blob/_generated/operations/_container_operations.py Adds generated create_session request builder + operation.
sdk/storage/azure-storage-blob/azure/storage/blob/_generated/aio/operations/_container_operations.py Adds generated async create_session operation.
sdk/storage/azure-storage-blob/azure/storage/blob/_generated/models/_models_py3.py Adds generated session models: CreateSessionConfiguration, CreateSessionResponse, SessionCredentials.
sdk/storage/azure-storage-blob/azure/storage/blob/_generated/models/_azure_blob_storage_enums.py Adds generated enum AuthenticationType.
sdk/storage/azure-storage-blob/azure/storage/blob/_generated/models/init.py Re-exports new generated models/enums.
sdk/storage/azure-storage-blob/azure/apiview-properties.json Updates API view surface list for new types/ops.
sdk/storage/azure-storage-blob/tests/conftest.py Adds test-proxy sanitizers for session token/key.
sdk/storage/azure-storage-blob/tests/test_container.py Adds recorded test validating bearer-vs-session auth behavior and per-container session usage.
sdk/storage/azure-storage-blob/CHANGELOG.md Documents the new opt-in session authentication feature.

Comment thread sdk/storage/azure-storage-blob/azure/storage/blob/_shared/policies.py Outdated
Comment thread sdk/storage/azure-storage-blob/tests/conftest.py Outdated
Comment thread sdk/storage/azure-storage-blob/tests/test_container.py Outdated
Comment thread sdk/storage/azure-storage-blob/tests/test_container.py Outdated
Comment thread sdk/storage/azure-storage-blob/azure/storage/blob/_shared/policies_async.py Outdated
Comment thread sdk/storage/azure-storage-blob/CHANGELOG.md
Copy link
Copy Markdown
Member

@jalauzon-msft jalauzon-msft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some comments on the sync policy itself, did not look at much else yet

if http_request.method != "GET":
return False
parsed = urlparse(http_request.url)
segments = [s for s in parsed.path.split("/") if s]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is more of a meta point for URL parsing in the PR as a whole but I'm leaving here as an example. Azurite/emulators use URLs like 127.0.0.1/account/container which would break all the container parsing logic. Not sure if we care about that (probably eventually we will need to)

Comment thread sdk/storage/azure-storage-blob/azure/storage/blob/_shared/policies.py Outdated
Comment thread sdk/storage/azure-storage-blob/azure/storage/blob/_shared/policies.py Outdated
Comment thread sdk/storage/azure-storage-blob/azure/storage/blob/_shared/policies.py Outdated
Comment thread sdk/storage/azure-storage-blob/azure/storage/blob/_shared/policies.py Outdated
Comment thread sdk/storage/azure-storage-blob/azure/storage/blob/_shared/policies.py Outdated
Comment thread sdk/storage/azure-storage-blob/azure/storage/blob/_shared/policies.py Outdated
Comment thread sdk/storage/azure-storage-blob/azure/storage/blob/_shared/base_client.py Outdated
Comment thread sdk/storage/azure-storage-blob/azure/storage/blob/_shared/base_client.py Outdated
StorageSessionPolicy(
account_name=self.account_name,
session_client_factory=_session_client_factory,
use_session=True,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is always passed as True? That probably means we don't need it in the policy and if the policy is present, it does its thing?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original design I had in mind was to add this policy blindly after StorageBearerTokenPolicy, and depending on the user passed in we just pass use_session thru. Then I realized there are some validation for us to do and that includes creating the session client factory (not worth creating if use_session is not enabled).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I think is the best approach here is to replace the explicit use_session flag/kwarg with the policy's mere presence in the pipeline as the enablement signal—so if the StorageSessionPolicy is wired in, session auth is on—and add a runtime _enabled switch that flips off automatically when the service responds with StorageErrorCode.FeatureNotEnabled, so the SDK stops attempting (and retrying) session auth on accounts that don't support it.

Comment thread sdk/storage/azure-storage-blob/azure/storage/blob/_shared/policies.py Outdated
Comment thread sdk/storage/azure-storage-blob/tests/test_container.py Outdated
captured = {}

def make_capture(label):
def _hook(response):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why hook inside a hook? You shouldn't need that. You may need to declare captured as nonlocal here though.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a way for the hook to distinguish between requests we're making. For example, an upload should use bearer token and download might use sessions. The label helps distinguish that. We still make the checks through captured[label]. I don't think we have to make it nonlocal if we are mutating captured in place.

Comment thread sdk/storage/azure-storage-blob/tests/test_container.py Outdated
for p in getattr(pipeline, "_impl_policies", []):
if type(p).__name__ == "StorageSessionPolicy":
return p
raise AssertionError("StorageSessionPolicy not found on the pipeline")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All these inline functions could be helpers, so they aren't duplicated? Even could be shared across sync and async. With the exception of maybe make_capture since it needs a local... but maybe there is something for that too.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done :p

assert auth.startswith("Session ")
return auth[len("Session ") :].split(":", 1)[0]

def find_session_policy(pipeline):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is pretty jank, but I'll allow it for now :D

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:D :D

@weirongw23-msft weirongw23-msft changed the base branch from main to storage/sessions-private June 4, 2026 19:25
)

def invalidate(self, container_name: str, session_token: Optional[str] = None) -> None:
if session_token is None:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need this if. It could remove a session that another thread put there.

@weirongw23-msft weirongw23-msft merged commit 0c5537d into Azure:storage/sessions-private Jun 5, 2026
3 checks passed
@weirongw23-msft weirongw23-msft deleted the weirongw23/sessions-private branch June 5, 2026 03:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Storage Storage Service (Queues, Blobs, Files)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants